﻿namespace MEFAddin
{
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using MEFAddin.Adapters;
    using MEFAddin.Interfaces;

    public class MEFControllerFactory
    {
        [ImportMany(typeof(IAddInController))]
        private List<IAddInController> _controllers;

        [ImportMany(typeof(IAddInCommand))]
        private List<IAddInCommand> _commands;

        /// <summary>
        /// Creates the specified addin CTX.
        /// </summary>
        /// <param name="addinCtx">The addin CTX.</param>
        /// <returns></returns>
        public IAddInController Create(AddInContext addinCtx)
        {
            var windowAdapter = new WindowAdapter(addinCtx);
            var loggingAdapter = new LoggingAdapter(addinCtx, windowAdapter, "ACSR Log");
            var commandAdapter = new CommandAdapter(addinCtx, loggingAdapter, windowAdapter);
            loggingAdapter.InitLogWindow();
            var adapter = new AddInAdapter(addinCtx, loggingAdapter, windowAdapter, commandAdapter);

            var catalog = new DirectoryCatalog(addinCtx.WorkingDirectory);
            CompositionContainer container = new CompositionContainer(catalog);
            container.SatisfyImportsOnce(this);

            loggingAdapter.LogMessage(string.Format("Imported {0} Controllers", this._controllers.Count));
            loggingAdapter.LogMessage(string.Format("Imported {0} Commands", this._commands.Count));

            var decorator = new MEFControllerChain();

            foreach (var controller in _controllers)
            {
                decorator = decorator.Register(controller);
                loggingAdapter.LogMessage(string.Format("Registered Controller: {0}", controller.GetType().FullName));
            }



            var commandsController = new MEFController();
            decorator = decorator.Register(commandsController);


            decorator.Initialize(addinCtx, adapter);

            foreach (var command in _commands)
            {
                var bar = commandAdapter.CreateCommandBar(command.CommandBarName);
                var commandObj = commandAdapter.AddCommand(bar, command.Name, command.Text, command.ToolTip, 13);
                command.CommandInstance = commandObj;
                commandsController.AddMEFCommand(command);
                command.Controller = commandsController;
                command.LoggingAdapter = loggingAdapter;
                command.WindowAdapter = windowAdapter;
                if (command.Bindings != null)
                {
                    commandObj.Bindings = command.Bindings;
                }
                command.Initialize();
                loggingAdapter.LogMessage(string.Format("Loaded Command: {0}", command.GetType().FullName));
            }

            return decorator;
        }
    }
}
